package com.hzit.pay.web.service.impl;

import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.hzit.pay.web.config.PayWebConfig;
import com.hzit.pay.web.config.RabbitMqConfig;
import com.hzit.pay.web.mapper.PayNoticeMapper;
import com.hzit.pay.web.mapper.PaySerialMapper;
import com.hzit.pay.web.model.PayNotice;
import com.hzit.pay.web.model.PaySerial;
import com.hzit.pay.web.service.IPayNotifyService;
import com.hzit.pay.web.service.IpaySerialService;
import com.hzit.payweb.api.enums.PayStatusEnum;
import com.hzit.payweb.api.resp.PayNotifyReq;
import com.hzit.payweb.api.utils.PayDigestUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.web.client.RestTemplate;

import java.util.Date;
import java.util.Map;

/**
 * 支付异步回调接口实现
 */
@Service
//@Scheduled + cron 定时任务， xxl-job 分布式任务调度系统
public class PayNotifyServiceImpl implements IPayNotifyService {


    private static final Logger logger = LoggerFactory.getLogger(PayNotifyServiceImpl.class);

    @Autowired
    private PayWebConfig payWebConfig;

    @Autowired
    private IpaySerialService paySerialService;

    @Autowired
    private PaySerialMapper paySerialMapper;

    @Autowired
    private RestTemplate restTemplate;


    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private PayNoticeMapper payNoticeMapper;


    @Override
    public String notify(Map<String,String> params) {

        //验证签名，验证请求是否支付宝发出来的
        try {
            boolean verify_result = AlipaySignature.rsaCheckV1(params, payWebConfig.getAlipayPublicKey(), "utf-8", "RSA2");
            if (!verify_result){
                logger.info("流水号：{}验证签名失败",params.get("out_trade_no"));
                return "fail";
            }

            //1.判断交易流水是否存在
            PaySerial paySerial = paySerialMapper.queryBySerialNo(params.get("out_trade_no"));

            if(ObjectUtils.isEmpty(paySerial)){
                return "fail";
            }

            //2.判断金额是否相等
            String totalAmt = params.get("total_amount");
            if(!paySerial.getPayAmt().equals(totalAmt)){
                return "fail";
            }

            //3.判断卖家账号是否一致

            //4、验证app_id是否为该商户本身。


            //5.更新交易流水。

            String tradeStatus = params.get("trade_status");

            if("TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus)){
                //更新交易流水为成功

                PaySerial upDatePaySerial = paySerialService.upDatePaySerial(params.get("out_trade_no"), String.valueOf(PayStatusEnum.PAY_SUCCESS.getCode()));

                //异步通知业务系统，更新订单服务或者还款服务等业务系统


                //第一次通知。发http请求

                //封装通知参数
                PayNotifyReq payNotifyReq = new PayNotifyReq();

                payNotifyReq.setMchId("1000"); //TODO
                payNotifyReq.setMchOrderId(upDatePaySerial.getMchOrderId());
                payNotifyReq.setPayAmt(upDatePaySerial.getPayAmt().toString());
                payNotifyReq.setPayStatus(upDatePaySerial.getStatus());
                payNotifyReq.setPayWay(upDatePaySerial.getPayWay());
                payNotifyReq.setPaySuccessTime(upDatePaySerial.getPaySuccessTime().toString());


                //生成签名
                try {
                    String sign = PayDigestUtil.getSign(payNotifyReq,"test3456");
                    payNotifyReq.setSign(sign);
                } catch (IllegalAccessException e) {
                    logger.error("IllegalAccessException",e);
                }

                //第一次
                String result = restTemplate.postForObject("",payNotifyReq,String.class);

                String status = "0";
                if(!"success".equals(result)){
                    //继续通知。 用mq。延时队列:支付宝，支付成功通知一次，4m一次，4m一次，8m，2h，2h，4h

                    // 设置这条消息的过期时间
                    rabbitTemplate.convertAndSend(RabbitMqConfig.BUSINESS_EXCHANGE_NAME, "", payNotifyReq, message -> {
                        MessageProperties messageProperties = message.getMessageProperties();
                        messageProperties.setExpiration("300000"); //时间配置
                        return message;
                    });
                    status = "-1";
                }

                //添加通知表：

                PayNotice payNotice = payNoticeMapper.selectByPaySerialNo(payNotifyReq.getPaySerialNo());

                if(ObjectUtils.isEmpty(payNotice)){
                    payNotice = new PayNotice();
                    payNotice.setNoticeCount(1);
                    payNotice.setNoticeTime(new Date());
                    payNotice.setStatus(status);
                    payNotice.setUpdateTime(new Date());
                    payNoticeMapper.insertSelective(payNotice);
                }
                return "success";

            }else{
                return "fail";
            }


        } catch (AlipayApiException e) {
            logger.error("AlipayApiException",e);
            return "fail";
        }


    }
}
